package ua.amsoft.brelok.manager;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List;

import org.apache.http.HttpResponse;
import org.apache.http.HttpStatus;
import org.apache.http.NameValuePair;
import org.apache.http.message.BasicNameValuePair;
import org.json.JSONException;
import org.json.JSONObject;

import android.test.AndroidTestCase;

public class HttpManagerTest extends AndroidTestCase {
    
    private static final String URL_UNKNOWN_HOST = "http://some.unknown.host";
    private static final String INVALID_URL = "some.invalid.url";
    private static final String URL_GOOGLE_COM = "http://google.com";
    private HttpManager httpManager;
    
    @Override
    protected void setUp() throws Exception {
        this.httpManager = new HttpManager();
    };
    
    public void testShouldDoSuccessfullGetRequest() {
        final HttpResponse response = this.httpManager.doGet(URL_GOOGLE_COM);
        assertNotNull(response);
        assertEquals(HttpStatus.SC_OK, response.getStatusLine().getStatusCode());
    }
    
    public void testShouldDoSuccessfullGetRequestWithNullHeaders() {
        final HttpResponse response = this.httpManager.doGet(URL_GOOGLE_COM, null);
        assertNotNull(response);
        assertEquals(HttpStatus.SC_OK, response.getStatusLine().getStatusCode());
    }
    
    public void testShouldDoUnsuccessfulGetRequestToInvalidUrl() {
        final HttpResponse response = this.httpManager.doGet(INVALID_URL);
        assertNull(response);
    }
    
    public void testShouldDoUnsuccessfulGetRequestToUnknownHost() {
        final HttpResponse response = this.httpManager.doGet(URL_UNKNOWN_HOST);
        assertNull(response);
    }
    
    public void testShouldDoSuccessfulPostRequest() throws IllegalStateException, IOException, JSONException {
        final String postURL = "http://httpbin.org/post";
        final List<NameValuePair> params = new ArrayList<NameValuePair>();
        params.add(new BasicNameValuePair("param", "value for param"));
        params.add(new BasicNameValuePair("second-param", "value for second-param"));
        final HttpResponse response = this.httpManager.doPost(postURL, params);
        assertNotNull(response);
        final InputStream httpResponseEntity = response.getEntity().getContent();
        assertNotNull(httpResponseEntity);
        assertEquals("application/json", response.getEntity().getContentType().getValue());
        final StringBuilder builder = readInputStream(httpResponseEntity);
        final JSONObject jsonObject = new JSONObject(builder.toString());
        assertNotNull(jsonObject);
        assertEquals("{\"second-param\":\"value for second-param\",\"param\":\"value for param\"}",
                jsonObject.getString("form"));
        assertEquals(HttpStatus.SC_OK, response.getStatusLine().getStatusCode());
    }
    
    public void testShouldDoUnsuccessfulPostRequestWithInvalidUrl() {
        final List<NameValuePair> params = null;
        final HttpResponse response = this.httpManager.doPost(INVALID_URL, params);
        assertNull(response);
    }
    
    public void testShouldDoUnsuccessfulPostRequestWithUnknowHost() {
        final List<NameValuePair> params = null;
        final HttpResponse response = this.httpManager.doPost(URL_UNKNOWN_HOST, params);
        assertNull(response);
    }

    private StringBuilder readInputStream(final InputStream httpResponseEntity) throws IOException {
        final BufferedReader br = new BufferedReader(new InputStreamReader(httpResponseEntity));
        final StringBuilder builder = new StringBuilder();
        String line;
        while ((line = br.readLine()) != null) {
            builder.append(line);
        }
        return builder;
    }
    
}
